/*
 * Copyright (c) 2012 RTCLab
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without modification, are
 * permitted provided that the following conditions are met:
 *
 * 1. Redistributions of source code must retain the above copyright notice, this list of
 *    conditions and the following disclaimer.
 *
 * 2. Redistributions in binary form must reproduce the above copyright notice, this list
 *    of conditions and the following disclaimer in the documentation and/or other materials
 *    provided with the distribution.
 *
 */

package com.rtckit {

import flash.media.Microphone;
import flash.system.Capabilities;
import flash.events.StatusEvent;
import flash.net.SharedObject;

public class SoftphoneConfig {
	
	public static var key:String = "123";
	public static var version:String = "1";

	// events TODO: move to events
	public var reportCallState:Object = function(callInfo:Object):void {};
	public var reportRegState:Object = function(regInfo:Object):void {};
	public var reportConnectState:Object = function():void {};
	public var reportMicState:Object = function():void {};
	
	public var reportVolumeChanged:Object = function(volume:Number):void {};
	public var reportMicChanged:Object = function():void {}

	// audio
	public var mic:Microphone = null;
	public var echo:Boolean = false;
	private var volume:Number = 100;
	private var micGain:Number = 80;
	private var micIndex:int = -1;

	// video
	public var video:Boolean = false;
	public var width:Number = 352;
	public var height:Number = 288;
	public var videoContainer:VideoContainer = null;
	public var preview:Boolean = false;
	
	// sounds
	public var ringback:String = 'ringback.mp3';
	public var ring:String = 'ring.mp3';
	public var busy:String = 'busy.mp3';
	public var noanswer:String = 'noanswer.mp3';
	
	// stresstest
	public var stresstest:Boolean = false;
	
	// local storage
	private var storage:SharedObject = null;
	
	public function SoftphoneConfig(params:Object = null) {
		if (!params)
			return;

		ringback = params.ringback;
		ring = params.ring;
		busy = params.busy;
		noanswer = params.noanswer;
		
		if (params.echo)
			echo = true;
		if (params.video)
			video = true;
		if (params.preview)
			preview = true;
		
		storage = SharedObject.getLocal('RTCKitSettings');
		if (storage.data.hasOwnProperty('micGain'))
			micGain = storage.data.micGain;
		if (storage.data.hasOwnProperty('volume'))
			volume = storage.data.volume;
		if (storage.data.hasOwnProperty('micIndex'))
			micIndex = storage.data.micIndex;
	}
	
	// microphone
	
	public function setupMicrophone():void {
		var idx:int = micIndex;
		if (idx < -1 || idx >= Microphone.names.length)
			idx = -1;
		mic = null;
		CONFIG::FP_10_3 {
			if (echo) {
				Logger.info('Using echo cancellation');
				mic = Microphone.getEnhancedMicrophone(idx);
			}
		}
		if (!mic)
			mic = Microphone.getMicrophone(idx);
		if (!mic)
			Logger.error('Microphone is not detected');
		else {
			mic.gain = micGain;
			mic.addEventListener(StatusEvent.STATUS, onMicStatus);
			reportMicState(!mic.muted);
		}
	}
	
	private function onMicStatus(e:StatusEvent):void {
		if (e.code == 'Microphone.Muted')
			reportMicState(false);
		else if (e.code == 'Microphone.Unmuted')
			reportMicState(true);
		else
			Logger.info('Uknown microphone event: ' + e.code);
	}
	
	private function normalize(val:Number):Number {
		if (val < 0)
			val = 0;
		else if (val > 100)
			val = 100;
		return val;
	}
	
	public function getMicGain():Number {
		return micGain;
	}
	
	public function setMicGain(val:Number):void {
		val = normalize(val);
		micGain = val;
		storage.data.micGain = val;
		if (mic)
			mic.gain = val;
	}
	
	public function getVolume():Number {
		return volume;
	}
	
	public function setVolume(val:Number):void {
		val = normalize(val);
		volume = val;
		storage.data.volume = val;
		reportVolumeChanged(val);
	}
	
	public function setMicIndex(idx:int):void {
		//if (idx == micIndex) return;
		if (idx < -1 || idx >= Microphone.names.length)
			idx = -1;
		micIndex = idx;
		storage.data.micIndex = idx;
		setupMicrophone();
		reportMicChanged();
	}
	
	public function getMicIndex():int {
		return micIndex;
	}
	
	public static function makeURL(server:String):String {
		var url:String = server;
		if (server.substr(0, 8) != 'rtmfp://')
			url = 'rtmfp://' + server + '/sf';
		if (url.indexOf('?') == -1)
			url += '?';
		else
			url += '&';
		url += 'key=' + key;
		url += '&fp=' + Capabilities.version.split(' ')[1];
		url += '&v=' + version;
		Logger.debug('Flash player version is ' + Capabilities.version);
		return url;
	}

}
}
